package com.zt.bigdata.practise.factory

import scala.beans.BeanProperty

/**
  *
  */

abstract class Car {
  var name: String = _

  def drive: Unit
}

class Benz extends Car {
  def drive {
    println(s"${this.name}  ----go-----------------------");
  }
}

class BMW extends Car {
  def drive {
    println(s"${this.name}  ----go-----------------------");
  }
}

/**
  * 简单工厂模式   缺点 新增一种车  需要改SimpleFactory工厂类
  */
object SimpleFactory {
  def createCar(car: String): Car = {
    car.toLowerCase match {
      case "benz" => new Benz
      case "bmw" => new BMW
    }
  }
}

/**
  * 工厂方法模式
  */
trait CarFactory {
  def createCar(car: String): Car
}

class BenzFactory extends CarFactory {
  override def createCar(car: String): Car = new Benz
}

class BMWFactory extends CarFactory {
  override def createCar(car: String): Car = new BMW
}

/**
  * 抽象工厂模式
  */
trait BenzCar {
  protected var name: String = _

  def drive: Unit
}

class BenzSportCar extends BenzCar {
  override def drive: Unit = println(s"${this.name}  ----BenzSportCar go-----------------------")
}

class BenzBusinessCar extends BenzCar {
  override def drive: Unit = println(s"${this.name}  ----BenzBusinessCar go-----------------------")
}

trait AudiCar {
  protected var name: String = _

  def drive: Unit
}

class AudiSportCar extends AudiCar {
  override def drive: Unit = println(s"${this.name}  ----AudiSportCar go-----------------------")
}

class AudiBusinessCar extends AudiCar {
  override def drive: Unit = println(s"${this.name}  ----AudiBusinessCar go-----------------------")
}


abstract class AbstractFactory {
  def createBenzCar(name: String): BenzCar

  def createAudiCar(name: String): AudiCar
}

class SportCarFactory extends AbstractFactory {
  override def createBenzCar(name: String): BenzCar = new BenzSportCar

  override def createAudiCar(name: String): AudiCar = new AudiSportCar
}

class BusinessCarFactory extends AbstractFactory {
  override def createBenzCar(name: String): BenzCar = new BenzBusinessCar

  override def createAudiCar(name: String): AudiCar = new AudiBusinessCar
}


/**
  * 简单工厂通过反射改进抽象工厂及其子工厂
  */
object AbstractFactoryImprove {
  def createBenzCar(car: String): BenzCar = Class.forName(car).newInstance().asInstanceOf[BenzCar]

  def createAudiCar(car: String): AudiCar = Class.forName(car).newInstance().asInstanceOf[AudiCar]
}


/**
  * 策略模式
  */

trait AudiMaker {
  var name: String = _

  def makeCar: Unit
}

class AudiA6Maker extends AudiMaker {
  override def makeCar: Unit = println(s"${this.name}  ----go-----------------------");
}

class AudiA4Maker extends AudiMaker {
  override def makeCar: Unit = println(s"${this.name}  ----go-----------------------");
}

/**
  * 销售部门----服务端
  */
class CarContext(var audiCar: AudiMaker) {
  def orderCar(): Unit = this.audiCar.makeCar
}

object BossSimpleFactory {
  def main(args: Array[String]): Unit = {
    //简单工厂模式
    //老板告诉司机我今天坐奔驰
    val car = SimpleFactory.createCar("Benz")
    car.name = "my Benz"
    //司机开着奔驰出发
    car.drive


    //工厂方法模式
    val d: CarFactory = new BenzFactory
    val c: Car = d.createCar("benz")
    c.name = "my benz"
    c.drive


    //抽象工厂模式
    val abstractFactory = new BusinessCarFactory
    val cc = abstractFactory.createAudiCar("")
    cc.drive


    val audiCar = AbstractFactoryImprove.createAudiCar(classOf[AudiSportCar].getName)
    audiCar.drive

    //简单工厂模式和策略模式
    //客户----客户端（这个客户是内行，什么都懂，他说我要A6，销售部门立刻给他a6，所以销售部门不用很懂）

    //客户说我要什么什么样子的车子，销售人员才知道他要什么样子的车子
    val audiCarMaker = new AudiA6Maker
    audiCarMaker.name = "a6"
    val context: CarContext = new CarContext(audiCarMaker)
    context.orderCar()
  }
}
